from decimal import Decimal
import json
from django.db import connection
from app.service.goods import query_goods_in_ids
from app.decorator import jwt_auth
from app.model.cs_carts import CsCarts
from app.service import cart, goods, goods_class, shop
from libs import common
from libs.common import success, error, get_ts
from libs.db import DB
from libs.form import RawJsonForm


@jwt_auth
def goods_list(request, auth):
    form = RawJsonForm(request.body)
    bill_num = form.get('bill_num')
    retained_flag = form.get_int('retained_flag')
    cart_status = form.get_int('status')
    cart_mode = form.get_int('cart_mode')
    if cart_status != -1:
        cart_status = 0
    try:
        with connection.cursor() as cursor:
            if retained_flag > 0:
                update_status_sql = 'update cs_carts set `status`=0 where bill_num=%s and `status`=-1'
                cursor.execute(update_status_sql, [bill_num])
            shop_id = auth.get('shop_id')
            cashier_id = auth.get('cashier_id')
            filters = {'shop_id': shop_id, 'cashier_id': cashier_id, 'bill_num': bill_num, 'status': cart_status}
            if cart_mode == 1:
                filters.update({'cart_typ in (1,2)': None})
            else:
                filters.update({'cart_typ': 0})
            dh = DB('cs_carts', conn=cursor)
            total = dh.count(filters)
            cart_arr = []
            total_sum = 0
            member_id = 0
            goods_id_arr = []
            if total > 0:
                cart_arr = dh.find('*', filters)
                for db_cart in cart_arr:
                    cart_goods_id = db_cart.get('goods_id')
                    if cart_goods_id > 0:
                        goods_id_arr.append(str(cart_goods_id))
                    total_sum = Decimal(db_cart.get('subtotal')) + Decimal(total_sum)
                    if member_id == 0 and db_cart.get('member_id') > 0:
                        member_id = db_cart.get('member_id')
                goods_dict = query_goods_in_ids(goods_id_arr)
                for db_cart1 in cart_arr:
                    if db_cart1['goods_id'] == 0:
                        db_cart1['goods_type'] = 0
                        db_cart1['menu_desc'] = ""
                    else:
                        cart_gooditem = goods_dict.get(db_cart1['goods_id'], None)
                        db_cart1['goods_type'] = cart_gooditem.is_fast_food
                        db_cart1['menu_desc'] = cart_gooditem.menu_desc
    except Exception as e:
        print(e)
    return success(cart_arr, total=total, member_id=member_id)


@jwt_auth
def add_goods(request, auth):
    form = RawJsonForm(request.body)
    goods_id = form.get_int('goods_id')
    if goods_id == 0:
        return error('商品ID为空')
    member_id = form.get_int('member_id')
    bill_num = form.get('bill_num')
    if bill_num == '':
        return error('无效的单号')

    shop_id = auth.get('shop_id')
    cashier_id = auth.get('cashier_id')
    db_goods_data = goods.query_goods_by_id(shop_id, goods_id)

    db_goods_id = db_goods_data.get('id', 0)
    if db_goods_id == 0:
        return error('查无此商品')
    db_barcode = db_goods_data.get('barcode', '')
    cart_typ = form.get_int('cart_typ')
    if cart_typ not in [0, 1, 2]:
        return error('无效的购物车类型')
    price_sign_dec = Decimal('1')
    if cart_typ == 1:
        price_sign_dec = Decimal('-1')
    db_goods_class_id = db_goods_data.get('class_id', 0)
    goods_class_name = ''
    if db_goods_class_id > 0:
        goods_class_name = goods_class.query_goods_class_name(db_goods_class_id)
    unit_price = db_goods_data.get('usdt_price')
    selling_price = unit_price
    drink_type = form.get_int('drink_type',1)
    drink_flavor = form.get('drink_flavor', '')
    is_fast_food = db_goods_data.get('is_fast_food')
    drink_spec = db_goods_data.get('drink_spec')
    if is_fast_food == 2:
        if drink_spec:
            drink_spec_arr = json.loads(drink_spec)
            for item in drink_spec_arr:
                dr_type = item["type"]
                if dr_type == drink_type:
                    unit_price = item["price"]
                    selling_price = item["price"]
    if is_fast_food == 2:
        #针对饮品类型商品不同的口味和型号要生成多条数据
        db_cart = cart.get_uncheck_cartdrink(shop_id, cashier_id, cart_typ, db_goods_id, bill_num,drink_type,drink_flavor)
    else:
        db_cart = cart.get_uncheck_cart(shop_id, cashier_id, cart_typ, db_goods_id, bill_num)
    db_cart_id = db_cart.get('id', 0)
    spec_typ = db_goods_data.get('spec_typ')
    unit = db_goods_data.get('unit')
    db_class_id = db_goods_data.get('class_id')
    db_class = goods.get_goods_class_by_id(db_class_id)
    risk_grade = db_class.get('db_class', 0)
    resp_data = {
        'goods_id': db_goods_id,
        'goods_name': db_goods_data.get('goods_name'),
        'selling_price': selling_price,
        'unit_price': unit_price,
        'spec_typ': spec_typ,
        'unit': unit,
        'risk_grade': risk_grade,
        'cart_typ': cart_typ,
    }
    amount_dec = form.get_int('amount',1) #Decimal('1')
    sig_barcode = ''
    add_new_row = False  # 针对称重商品，不同重量的条形码，添加到新行 
    if spec_typ == 1:
        amount_str = form.get('amount')
        amount_dec = common.str_to_dec(amount_str)
        if not amount_dec >= 0:
            amount_dec = Decimal('0')
        sig_barcode = form.get('barcode', '')
        db_sig_barcode = db_cart.get('sig_barcode', '')
        if sig_barcode == db_sig_barcode:
            return success(msg='称重商品，同一码不可累加')
        else:
            add_new_row = True
    amount_dec = amount_dec * price_sign_dec
    try:
        selling_price_dec = Decimal(selling_price)
        with connection.cursor() as cursor:
            goods_is_half = 0
            if spec_typ == 0:
                goods_is_half = db_goods_data.get('is_half')
                if goods_is_half == 0:
                    db_shop = shop.get_shop_by_id(cursor, shop_id, ['is_half'])
                    db_shop_is_half = db_shop.get('is_half', 0)
                    if db_shop_is_half > 0:
                        goods_is_half = db_shop_is_half
            if db_cart_id == 0 or add_new_row:
                if goods_is_half > 0:
                    # 退货半价算半价，换货第二件半价
                    if cart_typ == 1:
                        if goods_is_half == 1:
                           dec_subtotal = (selling_price_dec * amount_dec * common.to_dec(0.5)).quantize(Decimal('0.00'))
                        else:
                           dec_subtotal = (selling_price_dec * amount_dec * common.to_dec(0)).quantize(Decimal('0.00'))
                    else:
                        if is_fast_food == 2 and db_cart_id == 0:
                            _sql = 'select subtotal,amount from cs_carts where shop_id=%s and cashier_id=%s and goods_id=%s and bill_num=%s and cart_typ=%s and status = 0 and drink_type =%s'
                            bindings = [shop_id,cashier_id,db_goods_id,bill_num,cart_typ,drink_type]
                            cursor.execute(_sql,bindings)
                            rows_drink = cursor.fetchall()
                            if rows_drink is not None:
                                rows_amount = 0
                                rows_last = 0
                                for row in rows_drink:
                                    d_subtotal,d_amount = row
                                    rows_amount = rows_amount + d_amount
                                    rows_last = rows_last + d_subtotal
                                new_subtotal = common.calc_half_price(amount_dec + rows_amount, selling_price_dec,goods_is_half)
                                dec_subtotal = new_subtotal-rows_last
                            else:
                                dec_subtotal = (selling_price_dec * amount_dec).quantize(Decimal('0.00'))
                        else:
                            dec_subtotal = (selling_price_dec * amount_dec).quantize(Decimal('0.00'))
                else:
                    dec_subtotal = (selling_price_dec * amount_dec).quantize(Decimal('0.00'))
                cs_cart = CsCarts()
                cs_cart.shop_id = shop_id
                cs_cart.cashier_id = cashier_id
                cs_cart.goods_id = db_goods_id
                cs_cart.class_id = db_goods_class_id
                cs_cart.class_name = goods_class_name
                cs_cart.barcode = db_barcode
                cs_cart.sig_barcode = sig_barcode
                cs_cart.member_id = member_id
                cs_cart.bill_num = bill_num
                cs_cart.goods_name = db_goods_data.get('goods_name')
                cs_cart.selling_price = selling_price
                cs_cart.is_half = goods_is_half
                cs_cart.unit_price = unit_price
                cs_cart.amount = amount_dec
                cs_cart.spec_typ = spec_typ
                cs_cart.subtotal = dec_subtotal
                cs_cart.cart_typ = cart_typ
                cs_cart.status = 0
                now = get_ts()
                cs_cart.created = now
                cs_cart.updated = now
                cs_cart.drink_type = drink_type
                cs_cart.drink_flavor = drink_flavor
                cs_cart.save()
                resp_data['id'] = cs_cart.id
                resp_data['subtotal'] = dec_subtotal
                resp_data['amount'] = amount_dec
            else:
                db_cart_goods_num = db_cart.get('amount')
                new_amount = db_cart_goods_num + amount_dec
                if goods_is_half > 0:
                    # 退货半价算半价，换货第二件半价 
                    if cart_typ == 1:
                        if goods_is_half == 1:
                            dec_subtotal = (selling_price_dec * new_amount * common.to_dec(0.5)).quantize(Decimal('0.00'))
                        else:
                            dec_subtotal = (selling_price_dec * new_amount * common.to_dec(0)).quantize(Decimal('0.00'))
                    else:
                        dec_subtotal = common.calc_half_price(new_amount, selling_price_dec,goods_is_half)
                else:
                    dec_subtotal = (selling_price_dec * new_amount).quantize(Decimal('0.00'))
                new_cart_data = {
                    'amount': new_amount,
                    'selling_price': selling_price,
                    'subtotal': dec_subtotal,
                    'is_half':goods_is_half,
                }
                CsCarts.objects.filter(id=db_cart_id).update(**new_cart_data)
                resp_data['id'] = db_cart_id
                resp_data['subtotal'] = dec_subtotal
                resp_data['amount'] = new_amount
            resp_data['is_half'] = goods_is_half
    except Exception as ex:
        print(ex)
        return error()
    return success(resp_data)


@jwt_auth
def add_goods_by_price(request, auth):
    try:
        form = RawJsonForm(request.body)
        bill_num = form.get('bill_num')
        if bill_num == '':
            return error('无效的单号')
        price = form.get('price')
        price_dec = Decimal(price)
        if price_dec <= 0:
            return error('无效的无码商品价格')
        price = str(price_dec.quantize(Decimal('0.00')))
        member_id = form.get_int('member_id')
        cart_typ = form.get_int('cart_typ')
        if cart_typ not in [0, 1, 2]:
            return error('无效的购物车类型')
        price_sign_dec = Decimal('1')
        if cart_typ == 1:
            price_sign_dec = Decimal('-1')

        amount_dec = Decimal('1') * price_sign_dec
        subtotal_dec = price_dec * amount_dec
        shop_id = auth.get('shop_id')
        cashier_id = auth.get('cashier_id')
        now = get_ts()
        cs_cart = CsCarts()
        cs_cart.shop_id = shop_id
        cs_cart.cashier_id = cashier_id
        cs_cart.barcode = ''
        cs_cart.goods_id = 0
        cs_cart.member_id = member_id
        cs_cart.bill_num = bill_num
        cs_cart.goods_name = '无码商品'
        cs_cart.selling_price = price
        cs_cart.unit_price = price
        cs_cart.amount = amount_dec
        cs_cart.subtotal = subtotal_dec
        cs_cart.cart_typ = cart_typ
        cs_cart.status = 0
        cs_cart.created = now
        cs_cart.updated = now
        cs_cart.save()
        resp_data = {
            'id': cs_cart.id,
            'goods_id': 0,
            'goods_name': '无码商品',
            'selling_price': price,
            'unit_price': price,
            'subtotal': subtotal_dec,
            'amount': 1,
            'risk_grade': 0,
            'cart_typ': cart_typ,
        }
    except Exception as e:
        print(e)
        return error('无码商品加入购物车失败')
    return success(resp_data)


@jwt_auth
def update_goods(request, auth):
    err = '更新购物车失败'
    try:
        form = RawJsonForm(request.body)
        cart_id = form.get_int('id')
        if cart_id == 0:
            return error('无效的购物车ID')
        input_sell_price = form.get('selling_price', default=None)
        input_sell_price_dec = None
        if input_sell_price is not None:
            input_sell_price_dec = Decimal(input_sell_price).quantize(Decimal("0.00"))
            if input_sell_price_dec < 0:
                return error('无效的销售价格')
        shop_id = auth.get('shop_id')
        fields = ['goods_id', 'goods_name', 'selling_price', 'unit_price', 'amount', 'err', 'cart_typ', 'is_half']
        cs_cart = CsCarts.objects.filter(id=cart_id, shop_id=shop_id).values(*fields).get()
        cart_goods_id = cs_cart.get('goods_id', 0)
        db_cart_typ = cs_cart.get('cart_typ')
        remark = form.get('remark',"")
        amount_dec = form.get_dec('amount', None)
        if amount_dec is None:
            amount_dec = cs_cart.get('amount')
        elif amount_dec < 0:
            return error('无效的数量')
        update_err_arr = []

        if db_cart_typ == 1 and amount_dec > 0:
            amount_dec = amount_dec * Decimal('-1')

        risk_grade = 0
        if cart_goods_id > 0:
            db_goods = goods.query_goods_by_id(shop_id, cart_goods_id)
            db_goods_id = db_goods.get('id', 0)
            db_goods_class_id = db_goods.get('class_id')
            db_class = goods.get_goods_class_by_id(db_goods_class_id)
            risk_grade = db_class.get('risk_grade', 0)
            if db_goods_id == 0:
                update_err_arr.append('商品不存在')
            cart_err = cs_cart.get('err', None)
            if type(cart_err) is str:
                update_err_arr.append(cart_err)
        update_err = ';'.join(update_err_arr)

        is_input_price = 0
        selling_price = cs_cart.get('selling_price')
        if type(input_sell_price_dec) is Decimal and input_sell_price_dec != selling_price:
            selling_price = input_sell_price_dec
            subtotal_dec = input_sell_price_dec * amount_dec
            is_input_price = 1
        else:
            is_cart_half = cs_cart.get('is_half')
            if is_cart_half > 0:
                subtotal_dec = common.calc_half_price(amount_dec, selling_price,is_cart_half)
            else:
                subtotal_dec = selling_price * amount_dec
        subtotal_dec = subtotal_dec.quantize(Decimal('0.00'))
        now = get_ts()
        new_cart_data = {
            'updated': now,
            'amount': amount_dec,
            'selling_price': selling_price,
            'subtotal': subtotal_dec,
            'is_input_price': is_input_price,
            'remark':remark
        }
        if update_err != '':
            new_cart_data['err'] = update_err
        affected = CsCarts.objects.filter(id=cart_id).update(**new_cart_data)
        if affected == 1:
            cart_goods_name = cs_cart.get('goods_name')
            cart_unit_price = cs_cart.get('unit_price')
            return success({
                'id': cart_id,
                'goods_id': cart_goods_id,
                'goods_name': cart_goods_name,
                'selling_price': selling_price,
                'unit_price': cart_unit_price,
                'amount': amount_dec,
                'subtotal': subtotal_dec,
                'risk_grade': risk_grade,
                'cart_typ': db_cart_typ,
            })
    except CsCarts.DoesNotExist:
        return error('购物车不存在')
    except Exception as ex:
        print(ex)
        err = '更新购物车异常'
    return error(err)


@jwt_auth
def del_goods(request, auth):
    try:
        form = RawJsonForm(request.body)
        cart_id = form.get('id')
        shop_id = auth.get('shop_id')
        CsCarts.objects.filter(id=cart_id, shop_id=shop_id).delete()
    except Exception as ex:
        print(ex)
        return error()
    return success()


# 挂单
@jwt_auth
def retained(request, auth):
    try:
        form = RawJsonForm(request.body)
        bill_num = form.get('bill_num')
        member_id = form.get_int('member_id')
        if bill_num == '':
            return error('无效的单号')
        shop_id = auth.get('shop_id')
        up_data = {
            'status': -1,
        }
        if member_id > 0:
            up_data.update({'member_id': member_id})
        CsCarts.objects.filter(shop_id=shop_id, bill_num=bill_num, status=0).update(**up_data)
    except Exception as ex:
        print(ex)
        return error()
    return success()


# 取单/挂单列表
@jwt_auth
def retained_list(request, auth):
    form = RawJsonForm(request.body)
    p = form.get_page()
    shop_id = auth.get('shop_id')
    arr = []
    cursor = connection.cursor()
    try:
        count_sql = 'select count(distinct bill_num) num from cs_carts where shop_id=%s and status=%s'
        bindings = [shop_id, -1]
        cursor.execute(count_sql, bindings)
        row = cursor.fetchone()
        total = row[0]
        if total > 0:
            limit = ' limit {},{}'.format(p.offset, p.size)
            field_arr = ('bill_num', 'created')
            fields = ','.join(field_arr)
            sql = 'select ' + fields + ' from cs_carts where shop_id=%s and status=%s group by bill_num' \
                                       ' order by updated desc' + limit
            cursor.execute(sql, bindings)
            rows = cursor.fetchall()
            for item in rows:
                arr.append({'bill_num': item[0], 'created': item[1]})
    except Exception as ex:
        print(ex)
        return error()
    finally:
        cursor.close()
    return success(arr, total=total, page=p.page, size=p.size)


# 作废
@jwt_auth
def del_cart(request, auth):
    try:
        form = RawJsonForm(request.body)
        bill_num = form.get('bill_num')
        if bill_num == '':
            return error('无效的单号')
        shop_id = auth.get('shop_id')
        CsCarts.objects.filter(shop_id=shop_id, bill_num=bill_num, status=-1).delete()
    except Exception as ex:
        print(ex)
        return error()
    return success()
